/**
 * Alipay.com Inc.
 * Copyright (c) 2005-2013 All Rights Reserved.
 */
package com.pingan.mobilegw.core.service.invoke.processor;

import com.alibaba.common.lang.StringUtil;
import com.alibaba.fastjson.JSON;
import com.pingan.mobilegw.adapterservice.ResultEnum;
import com.pingan.mobilegw.adapterservice.TargetResponseObject;
import com.pingan.mobilegw.core.model.GatewayRequest;
import com.pingan.mobilegw.core.model.GatewayResponse;
import com.pingan.mobilegw.core.model.ServiceConfig;
import com.pingan.mobilegw.core.model.comm.TargetRequestObject;
import com.pingan.mobilegw.core.model.constant.ContextConstant;
import com.pingan.mobilegw.core.model.exception.MgwException;
import com.pingan.mobilegw.core.model.request.SingleRequestBody;
import com.pingan.mobilegw.core.service.business.Processor;
import com.pingan.mobilegw.core.service.invoke.proxy.MobileAdapterServiceInvokeProxyImpl;
import com.pingan.mobilegw.core.service.invoke.proxy.MobileAdapterWithCallbackProxyImpl;
import com.pingan.mobilegw.core.service.invoke.proxy.MofaInvokeProxy;
import com.pingan.mobilegw.core.service.util.ContextUtil;
import com.pingan.mobilegw.core.service.util.ResponseUtil;
import com.pingan.mobilegw.mobileservice.invoke.MobileRpcHolder;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.HashMap;
import java.util.Map;

/**
 * 动态远程调用处理器
 * 
 * @author jiadao
 * @version $Id: MobileAdapterProxyProcesser.java, v 0.1 2013-4-16 下午9:11:02 jiadao Exp $
 */
public class MobileAdapterProxyProcesser implements Processor {

    /** logger */
    private static final Log logger = LogFactory.getLog(MobileAdapterProxyProcesser.class);

    @Autowired
    /** 动态远程调用代理 同步模式 */
    private MobileAdapterServiceInvokeProxyImpl mobileAdapterServiceInvokeProxyImpl=new MobileAdapterServiceInvokeProxyImpl();

    @Autowired
    /** 动态远程调用代理 异步模式 */
    private MobileAdapterWithCallbackProxyImpl mobileAdapterWithCallbackProxyImpl=new MobileAdapterWithCallbackProxyImpl();

    /**
     * 
     * @see com.pingan.mobilegw.core.service.business.Processor#process(com.pingan.mobilegw.core.model.GatewayRequest)
     */
    @Override
    public GatewayResponse process(GatewayRequest gatewayRequest) {

        // 构造远程请求对象
        TargetRequestObject target = constructRequestObject(gatewayRequest);

        // 远程调用
        TargetResponseObject result = null;
        try {
            if (ContextUtil.isAsyncStarting(gatewayRequest.getHttpRequest())) {
                result = (TargetResponseObject) mobileAdapterWithCallbackProxyImpl.invoke(target);
            } else {
                result = (TargetResponseObject) mobileAdapterServiceInvokeProxyImpl.invoke(target);
            }
        } catch (MgwException e) {
            logger.warn("远程调用异常", e);
            return ResponseUtil.buildErrorResponse(e.getResultCode());
        } catch (Exception e) {
            logger.error("调起远程ws出错！", e);
            return ResponseUtil.buildErrorResponse(ResultEnum.RemoteAccessException);
        }

        if (ContextUtil.isAsyncStarting(gatewayRequest.getHttpRequest()) && result == null) {
            return null;
        } else {
            // 增量更新
            MobileRpcHolder.getIncrementalChanges().putAll(result.getChangeAttributes());
            // 返回结果
            return buildGatewayResponse(result);
        }
    }

    /**
     * 根据远程返回的对象构造GatewayResponse对象
     * 
     * @param result
     * @return
     */
    private GatewayResponse buildGatewayResponse(TargetResponseObject result) {
        // 获取错误枚举
        ResultEnum resultEnum = ResultEnum.getResultEnumByCode(result.getResultStatus());
        // 构造网关响应 
        GatewayResponse gatewayResponse = ResponseUtil.buildResponse(resultEnum.getCode(),
            resultEnum.getMemo(), JSON.parseObject(result.getResult(), Object.class));
        return gatewayResponse;
    }

    /**
     * 构建请求远程请求对象
     * 
     * @param gatewayRequest
     * @return
     */
    private TargetRequestObject constructRequestObject(GatewayRequest gatewayRequest) {
        SingleRequestBody requestBody = (SingleRequestBody) gatewayRequest.getRequestBody();
        String uniqueId = "11";//TODO ContextLifeManager.checkAPIQuery() == null ? CtxUtils.getUUID()
           // : ContextLifeManager.checkAPIQuery().getInvokeId();//上下文ID

        TargetRequestObject target = new TargetRequestObject();
        target.setGatewayRequest(gatewayRequest);
        target.getMobileContext().setSession(gatewayRequest.getCacheSession());

        String str = requestBody.getRequestData();
        //        LoggerUtil.info(logger, "gw合并:" + str);
        //        str = StringUtil.replace(str, "[\"", "");
        //        str = StringUtil.replace(str, "\"]", "");
        //        JSONArray array = new JSONArray();
        //        array.add(str);
        //        LoggerUtil.info(logger, "gw合并2:" + str);
        //        String jstr = JSONArray.toJSONString(array);

        target.setRequestData(str);
        target.setUniqueId(uniqueId);

        Map<String, String> headers = gatewayRequest.getHeaders();
        if (headers != null) {
            target.getMobileContext().setHeaders(headers);
        }
        Map<String, String> cookies = gatewayRequest.getCookies();
        if (cookies != null) {
            target.getMobileContext().setCookies(gatewayRequest.getCookies());
        }

        //快捷降级开关传递
        String resCode = (String) gatewayRequest.getHttpRequest().getAttribute(
            ContextConstant.MSP_SWITCH_1);
        String gwSwitch = (String) gatewayRequest.getHttpRequest().getAttribute(
            ContextConstant.MSP_SWITCH_2);

        if (StringUtil.equals(requestBody.getOperationType(), "pingan.msp.cashier.dispatch")) {
            if (null == target.getMobileContext().getHeaders()) {
                Map<String, String> nMap = new HashMap<String, String>();
                nMap.put("X-GW-MSP-SWITCH", resCode);
                nMap.put("X-GW-SWITCH", gwSwitch);
                target.getMobileContext().setHeaders(nMap);

            } else {
                target.getMobileContext().getHeaders().put("X-GW-MSP-SWITCH", resCode);
                target.getMobileContext().getHeaders().put("X-GW-SWITCH", gwSwitch);
            }
        }

        ServiceConfig serviceConfig = (ServiceConfig) gatewayRequest.getHttpRequest().getAttribute(
            ContextConstant.SERVICE_CONFIG);

        //TODO
        serviceConfig=new ServiceConfig();

        target.setServiceConfig(serviceConfig);
        target.getMobileContext().setSysName(serviceConfig.getSysName());
        target.getMobileContext().setClassName(serviceConfig.getInterfaceType());
        target.getMobileContext().setMethodName(serviceConfig.getMethodName());
        target.getMobileContext().setOperationType(requestBody.getOperationType());

        return target;

    }



}
